<?php

/*
 * Copyright (C) 2009 - 2011 Pham Cong Dinh
 *
 * This file is part of Spica.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

/**
 * Represents Redis's LPUSH command which add a string value to the head
 * of the <code>LIST</code> stored at the provided key.
 *
 * namespace spica\core\datasource\redis\cmd\LPUSH;
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\redis\cmd
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 26, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: List.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaRedisLPUSH implements SpicaRedisCommand
{
    /**
     * The provided key.
     *
     * @var string
     */
    protected $_key;

    /**
     * The provided value.
     *
     * @var string
     */
    protected $_val;

    /**
     * The provided value length.
     *
     * @var int
     */
    protected $_len;

    /**
     * Constructs an object of <code>SpicaRedisLPUSH</code> to add a string
     * value to the head of the <code>LIST</code> stored at the provided key.
     *
     * @throws InvalidArgumentException
     * @param  string $key
     * @param  string $value
     */
    public function __construct($key, $value)
    {
        if (true === empty($value))
        {
            throw new InvalidArgumentException('Parameter $value can not be empty.');
        }

        $this->_key = $key;
        $this->_val = $value;
        $this->_len = strlen($value);
    }

    /**
     * Sets key.
     *
     * @param string $key
     */
    public function setKey($key)
    {
        $this->_key = $key;
    }

    /**
     * Sets value.
     *
     * @throws InvalidArgumentException
     * @param string $val
     */
    public function setValue($val)
    {
        if (true === empty($val))
        {
            throw new InvalidArgumentException('Parameter $value can not be empty.');
        }

        $this->_val = $val;
        $this->_len = strlen($value);
    }

    /**
     * Gets the command string.
     *
     * @return string
     */
    public function toString()
    {
        return 'LPUSH '.$this->_key.' '.$this->_len.SpicaRedisCommand::NL.$this->_val.SpicaRedisCommand::NL;
    }

    /**
     * Is this command subject to hashing?
     *
     * @return bool
     */
    public function supportsHash()
    {
        return true;
    }
}

/**
 * Represents Redis's RPUSH command which adds a string value to the end of the
 * <code>LIST</code> stored at the provided key.
 *
 * namespace spica\core\datasource\redis\cmd\RPUSH;
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\redis\cmd
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 26, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: List.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaRedisRPUSH extends SpicaRedisLPUSH
{
    /**
     * Gets the command string.
     *
     * @return string
     */
    public function toString()
    {
        return 'RPUSH '.$this->_key.' '.$this->_len.SpicaRedisCommand::NL.$this->_val.SpicaRedisCommand::NL;
    }
}

/**
 * Represents Redis's LPOP command that fetches and remove the first
 * element of the <code>LIST</code> stored at the provided key.
 *
 * namespace spica\core\datasource\redis\cmd\LPOP;
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\redis\cmd
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 26, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: List.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaRedisLPOP implements SpicaRedisCommand
{
    /**
     * The provided key.
     *
     * @var string
     */
    protected $_key;

    /**
     * Constructs an object of <code>SpicaRedisLPOP</code> to fetches and remove the first
     * element of the <code>LIST</code> stored at the provided key.
     *
     * @param string $key
     */
    public function __construct($key)
    {
        $this->_key = $key;
    }

    /**
     * Sets key.
     *
     * @param string $key
     */
    public function setKey($key)
    {
        $this->_key = $key;
    }

    /**
     * Gets the command string.
     *
     * @return string
     */
    public function toString()
    {
        return 'LPOP '.$this->_key.SpicaRedisCommand::NL;
    }

    /**
     * Is this command subject to hashing?
     *
     * @return bool
     */
    public function supportsHash()
    {
        return true;
    }
}

/**
 * Represents Redis's RPOP command which returns and removes the last
 * element of the <code>LIST</code> stored at the provided key.
 *
 * namespace spica\core\datasource\redis\cmd\RPOP;
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\redis\cmd
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 26, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: List.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaRedisRPOP extends SpicaRedisLPOP
{
    /**
     * Gets the command string.
     *
     * @return string
     */
    public function toString()
    {
        return 'RPOP '.$this->_key.SpicaRedisCommand::NL;
    }
}

/**
 * Represents Redis's LLEN command which returns the length
 * of the <code>LIST</code> stored at the provided key.
 *
 * namespace spica\core\datasource\redis\cmd\LLEN;
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\redis\cmd
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 26, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: List.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaRedisLLEN extends SpicaRedisLPOP
{
    /**
     * Gets the command string.
     *
     * @return string
     */
    public function toString()
    {
        return 'LLEN '.$this->_key.SpicaRedisCommand::NL;
    }
}

/**
 * Represents Redis's LRANGE command which returns the specified elements
 * of the <code>LIST</code> stored at the provided key.
 *
 * namespace spica\core\datasource\redis\cmd\LRANGE;
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\redis\cmd
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 26, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: List.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaRedisLRANGE implements SpicaRedisCommand
{
    /**
     * The provided key.
     *
     * @var string
     */
    protected $_key;

    /**
     * The start index.
     *
     * @var string
     */
    protected $_start;

    /**
     * The end index.
     *
     * @var int
     */
    protected $_end;

    /**
     * Constructs an object of <code>SpicaRedisLRANGE</code> to return
     * the specified elements of the <code>LIST</code> stored at the provided key.
     *
     * @param string $key   The provided key
     * @param int    $start The start index
     * @param int    $end   The end index
     */
    public function __construct($key, $start, $end)
    {
        $this->_key   = $key;
        $this->_start = $start;
        $this->_end   = $end;
    }

    /**
     * Sets key.
     *
     * @param string $key
     */
    public function setKey($key)
    {
        $this->_key = $key;
    }

    /**
     * Sets start and end index.
     *
     * @param int $start The start index
     * @param int $end   The end index
     */
    public function setIndex($start, $end)
    {
        $this->_start = $start;
        $this->_end   = $end;
    }

    /**
     * Gets the command string.
     *
     * @return string
     */
    public function toString()
    {
        return 'LRANGE '.$this->_key.' '.$this->_start.' '.$this->_end.SpicaRedisCommand::NL;
    }

    /**
     * Is this command subject to hashing?
     *
     * @return bool
     */
    public function supportsHash()
    {
        return true;
    }
}

/**
 * Represents Redis's LINDEX command which get a single value back
 * from a <code>LIST</code> stored at the provided key using a specified index.
 *
 * namespace spica\core\datasource\redis\cmd\LINDEX;
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\redis\cmd
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 27, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: List.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaRedisLINDEX implements SpicaRedisCommand
{
    /**
     * The provided key.
     *
     * @var string
     */
    protected $_key;

    /**
     * The provided index.
     *
     * @var string
     */
    protected $_index;

    /**
     * Constructs an object of <code>SpicaRedisLINDEX</code> to get a single value back
     * from a <code>LIST</code> stored at the provided key using a specified index.
     *
     * @param string $key A list name
     * @param string $index An index
     */
    public function __construct($key, $index)
    {
        $this->_key   = $key;
        $this->_index = $index;
    }

    /**
     * Sets a list name and index.
     *
     * @param string $key A list name
     * @param int $index Zero-based index
     */
    public function setKey($key, $index)
    {
        $this->_key   = $key;
        $this->_index = $index;
    }

    /**
     * Gets the command string.
     *
     * @return string
     */
    public function toString()
    {
        return 'LINDEX '.$this->_key.' '.$this->_index.SpicaRedisCommand::NL;
    }

    /**
     * Is this command subject to hashing?
     *
     * @return bool
     */
    public function supportsHash()
    {
        return true;
    }
}

/**
 * Represents Redis's LTRIM command which trims an existing <code>LIST</code> stored at
 * the provided key so that it will contain only the specified range of elements specified.
 *
 * namespace spica\core\datasource\redis\cmd\LTRIM;
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\redis\cmd
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 28, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: List.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaRedisLTRIM extends SpicaRedisLRANGE
{
    /**
     * Gets the command string.
     *
     * @return string
     */
    public function toString()
    {
        return 'LTRIM '.$this->_key.' '.$this->_start.' '.$this->_end.SpicaRedisCommand::NL;
    }
}

/**
 * Represents Redis's LSET command which set a new string value to the specified index
 * of the <code>LIST</code> stored at the provided key.
 *
 * namespace spica\core\datasource\redis\cmd\LSET;
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\redis\cmd
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 28, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: List.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaRedisLSET implements SpicaRedisCommand
{
    /**
     * The provided key.
     *
     * @var string
     */
    protected $_key;

    /**
     * The provided value.
     *
     * @var string
     */
    protected $_val;

    /**
     * The provided index in the list.
     *
     * @var int
     */
    protected $_index;

    /**
     * The provided value length.
     *
     * @var int
     */
    protected $_len;

    /**
     * Constructs an object of <code>SpicaRedisLSET</code> to set a new string value to
     * the specified index of the <code>LIST</code> stored at the provided key.
     *
     * @throws InvalidArgumentException
     * @param  string $key List name
     * @param  int    $index List index (can be negative)
     * @param  string $value
     */
    public function __construct($key, $index, $value)
    {
        if (true === empty($value))
        {
            throw new InvalidArgumentException('Parameter $value can not be empty.');
        }

        $this->_key   = $key;
        $this->_val   = $value;
        $this->_index = $index;
        $this->_len   = strlen($value);
    }

    /**
     * Sets list name.
     *
     * @param string $key A list name
     */
    public function setKey($key)
    {
        $this->_key = $key;
    }

    /**
     * Sets value.
     *
     * @throws InvalidArgumentException
     * @param  int    $index List index (can be negative)
     * @param  string $value
     */
    public function setValue($index, $value)
    {
        if (true === empty($value))
        {
            throw new InvalidArgumentException('Parameter $value can not be empty.');
        }

        $this->_val   = $value;
        $this->_index = $index;
        $this->_len   = strlen($value);
    }

    /**
     * Gets the command string.
     *
     * @return string
     */
    public function toString()
    {
        return 'LSET '.$this->_key.' '.$this->_index.' '.$this->_len.SpicaRedisCommand::NL.$this->_val.SpicaRedisCommand::NL;
    }

    /**
     * Is this command subject to hashing?
     *
     * @return bool
     */
    public function supportsHash()
    {
        return true;
    }
}

/**
 * Represents Redis's RPOPLPUSH command which return and remove the last element of the source list,
 * and push the element as the first element of the target list.
 *
 * namespace spica\core\datasource\redis\cmd\RPOPLPUSH;
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\redis\cmd
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 28, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: List.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaRedisRPOPLPUSH implements SpicaRedisCommand
{
    /**
     * The source list.
     *
     * @var string
     */
    protected $_src;

    /**
     * The destination list.
     *
     * @var string
     */
    protected $_dest;

    /**
     * Length of the target list key name.
     *
     * @var int
     */
    protected $_len;

    /**
     * Constructs an object of <code>SpicaRedisRPOPLPUSH</code> to return and remove the last element
     * of the $source list, and push the element as the first element of the $destination list.
     *
     * The affected element in the $source list will be returned in a bulk reply.
     *
     * @throws InvalidArgumentException
     * @param  string $source Key name of the source list
     * @param  int    $dest   Key name of the destination list
     */
    public function __construct($source, $dest)
    {
        if (true === empty($source) || true === empty($dest))
        {
            throw new InvalidArgumentException('Parameter $dest or $source can not be empty.');
        }

        $this->_src  = $source;
        $this->_dest = $dest;
        $this->_len  = strlen($dest);
    }

    /**
     * Sets source list name.
     *
     * @param string $source A list name
     */
    public function setSource($source)
    {
        $this->_src = $source;
    }

    /**
     * Sets destination list name.
     *
     * @param string $dest A list name
     */
    public function setDestination($dest)
    {
        $this->_dest = $dest;
        $this->_len  = strlen($dest);
    }

    /**
     * Gets the command string.
     *
     * @return string
     */
    public function toString()
    {
        return 'RPOPLPUSH '.$this->_src.' '.$this->_len.SpicaRedisCommand::NL.$this->_dest.SpicaRedisCommand::NL;
    }

    /**
     * Is this command subject to hashing?
     *
     * @return bool
     */
    public function supportsHash()
    {
        return true;
    }
}

/**
 * Represents Redis's LREM command which removes a specified number of first occurrences of the value element
 * from the list stored at the provided key.
 *
 * namespace spica\core\datasource\redis\cmd\LREM;
 *
 * @category   spica
 * @package    core
 * @subpackage datasource\redis\cmd
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      December 28, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: List.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaRedisLREM implements SpicaRedisCommand
{
    /**
     * The provided list name.
     *
     * @var string
     */
    protected $_key;

    /**
     * The number of first occurrences to be removed.
     *
     * @var int
     */
    protected $_count;

    /**
     * The string value.
     *
     * @var string
     */
    protected $_val;

    /**
     * Length of the string value.
     *
     * @var int
     */
    protected $_len;

    /**
     * Constructs an object of <code>SpicaRedisRPOPLPUSH</code> to removes a specified
     * number of first occurrences of the value element from the list stored at the provided key..
     *
     * The number of affected elements will be returned in an integer reply.
     *
     * @throws InvalidArgumentException
     * @param  string $key   Key name of the list
     * @param  int    $value The string value to check in the list
     * @param  int    $count Number of first occurences of the $value in the list to be removed
     */
    public function __construct($key, $value, $count)
    {
        if (true === empty($value))
        {
            throw new InvalidArgumentException('Parameter $value can not be empty.');
        }

        $this->_key   = $key;
        $this->_count = $count;
        $this->_val   = $value;
        $this->_len   = strlen($value);
    }

    /**
     * Sets source list name.
     *
     * @param string $key Key name of the list
     */
    public function setKey($key)
    {
        $this->_key = $key;
    }

    /**
     * Sets string value and the number of its first occurences to be removed.
     *
     * @param int $value The string value to check in the list
     * @param int $count Number of first occurences of the $value in the list to be removed
     */
    public function setValue($value, $count)
    {
        $this->_count = $count;
        $this->_val   = $value;
        $this->_len   = strlen($value);
    }

    /**
     * Gets the command string.
     *
     * @return string
     */
    public function toString()
    {        
        return 'LREM '.$this->_key.' '.$this->_count.' '.$this->_len.SpicaRedisCommand::NL.$this->_val.SpicaRedisCommand::NL;
    }

    /**
     * Is this command subject to hashing?
     *
     * @return bool
     */
    public function supportsHash()
    {
        return true;
    }
}

?>